/**
 * Created by Sasha on 2017/8/8.
 */


/************************************************************ String字符串原型扩展方法 ************************************************************/

/**
 * 字符串转换为日期型（原型扩展或重载）
 * @returns {Date} 日期
 */
String.prototype.toDate = function () {
    var converted = Date.parse(this);
    var myDate = new Date(converted);
    if (isNaN(myDate)) {
        var arys = this.split('-');
        myDate = new Date(arys[0], --arys[1], arys[2]);
    }
    return myDate;
};

/**
 * 检查是否含有utf16字符
 * @returns 如果是返回false，否则返回true
 */
String.prototype.isUtf16 = function () {
    var re = /[\ud800-\udbff][\udc00-\udfff]/g;
    var result = re.test(this);
    return result;
};


/************************************************************ Array数组原型扩展方法 ************************************************************/

/**
 * 删除数组某个元素
 * @param val
 */
Array.prototype.remove = function(val) {
    var index = this.indexOf(val);
    if (index > -1) {
        this.splice(index, 1);
    }
};


/************************************************************ Date日期原型扩展方法 ************************************************************/

/**
 * 日期格式化（原型扩展或重载）
 * 格式 YYYY/yyyy/YY/yy 表示年份
 * MM/M 月份
 * W/w 星期
 * dd/DD/d/D 日期
 * hh/HH/h/H 时间
 * mm/m 分钟
 * ss/SS/s/S 秒
 * @param {formatStr} 格式模版
 * @type string
 * @returns 日期字符串
 */
Date.prototype.format = Date.prototype.format || function (formatStr) {
    var str = formatStr;
    var Week = ['日', '一', '二', '三', '四', '五', '六'];
    str = str.replace(/yyyy|YYYY/, this.getFullYear());
    str = str.replace(/yy|YY/, (this.getYear() % 100) > 9 ? (this.getYear() % 100).toString() : '0' + (this.getYear() % 100));
    str = str.replace(/MM/, (this.getMonth() + 1) > 9 ? (this.getMonth() + 1).toString() : '0' + (this.getMonth() + 1));
    str = str.replace(/M/g, this.getMonth());
    str = str.replace(/w|W/g, Week[this.getDay()]);
    str = str.replace(/dd|DD/, this.getDate() > 9 ? this.getDate().toString() : '0' + this.getDate());
    str = str.replace(/d|D/g, this.getDate());
    str = str.replace(/hh|HH/, this.getHours() > 9 ? this.getHours().toString() : '0' + this.getHours());
    str = str.replace(/h|H/g, this.getHours());
    str = str.replace(/mm/, this.getMinutes() > 9 ? this.getMinutes().toString() : '0' + this.getMinutes());
    str = str.replace(/m/g, this.getMinutes());
    str = str.replace(/ss|SS/, this.getSeconds() > 9 ? this.getSeconds().toString() : '0' + this.getSeconds());
    str = str.replace(/s|S/g, this.getSeconds());
    return str;
};


/**
 * 将指定的天数加到此实例的值上
 * @param value
 * @returns {Date}
 */
Date.prototype.addDays = function (value) {
    var date = this.getDate();
    this.setDate(date + value);
    return this;
},

/**
 * 将指定的星期数加到此实例的值上
 * @param value
 * @returns {Date}
 */
Date.prototype.addWeeks = function (value) {
    return this.addDays(value * 7);
},


/**
 * 将指定的月份数加到此实例的值上
 * @param value
 * @returns {Date}
 */
Date.prototype.addMonths = function (value) {
    var month = this.getMonth();
    this.setMonth(month + value);
    return this;
},

/**
 * 将指定的年份数加到此实例的值上
 * @param value
 * @returns {Date}
 */
Date.prototype.addYears =  function (value) {
    var year = this.getFullYear();
    this.setFullYear(year + value);
    return this;
};

/**
 * 比较日期差（原型扩展或重载）
 * @param {strInterval} 日期类型:'y、m、d、h、n、s、w'
 * @param {dtEnd} 格式为日期型或者 有效日期格式字符串
 * @type int
 * @returns 比较结果
 */
Date.prototype.dateDiff = function (strInterval, dtEnd) {
    var dtStart = this;
    if (typeof dtEnd == 'string') { //如果是字符串转换为日期型
        dtEnd = dtEnd.toDate();
    }
    switch (strInterval) {
        case 's' :
            return parseInt((dtEnd - dtStart) / 1000);
        case 'n' :
            return parseInt((dtEnd - dtStart) / 60000);
        case 'h' :
            return parseInt((dtEnd - dtStart) / 3600000);
        case 'd' :
            return parseInt((dtEnd - dtStart) / 86400000);
        case 'w' :
            return parseInt((dtEnd - dtStart) / (86400000 * 7));
        case 'm' :
            return (dtEnd.getMonth() + 1) + ((dtEnd.getFullYear() - dtStart.getFullYear()) * 12) - (dtStart.getMonth() + 1);
        case 'y' :
            return dtEnd.getFullYear() - dtStart.getFullYear();
    }
};


/************************************************************ Number数字原型扩展方法 ************************************************************/

/**
 * 数字格式变成货币数字格式（原型扩展或重载）
 * @returns {string}
 */
Number.toCurrency = function (value) {
    if(value) {
        var minus = Number(value) < 0 ? '-' : '';
        var str = Math.abs( Number(value) ).toFixed(2).toString();
        var pointNum = '';
        if(str.indexOf('.')!=-1){
            pointNum = '.' + str.split('.')[1];
            str = str.split('.')[0];
        }
        var n = str.length % 3;
        if(n){
            return minus + str.slice(0,n) + str.slice(n).replace(/(\d{3})/g,',$1') + pointNum;
        }else{
            return minus + str.replace(/(\d{3})/g,',$1').slice(1) + pointNum;
        }
    }else{
        return value==0 ? value : '';
    }
};
/**
 * 转换数字为货币格式
 * @param places 保留小数位数
 * @param symbol 货币前的符号（比如$,￥）
 * @param thousand 每3位数间隔的标志
 * @param decimal 小数点位置的符号，默认为"."可更改
 * @returns {string}
 */
Number.prototype.formatMoney = function (places, symbol, thousand, decimal) {
    places = !isNaN(places = Math.abs(places)) ? places : 2;
    symbol = symbol !== undefined ? symbol : "";
    thousand = thousand || ",";
    decimal = decimal || ".";
    var number = this,
        negative = number < 0 ? "-" : "",
        i = parseInt(number = Math.abs(+number || 0).toFixed(places), 10) + "",
        j = (j = i.length) > 3 ? j % 3 : 0;
    return symbol + negative + (j ? i.substr(0, j) + thousand : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousand) + (places ? decimal + Math.abs(number - i).toFixed(places).slice(2) : "");
};


/***--------------------------------- Vue公用指令之 v-w-title="msg" 解决自定义样式titile-------------------------------------***/
import Vue from 'vue';

// body元素
let body = document.querySelector('body');
// head元素
let head = document.querySelector('head');

// 添加样式
let style = document.createElement('style');
style.innerHTML = '.w-title{position:fixed;padding:5px 11px;line-height:20px;border:1px solid #E5D7A8;box-shadow:0 2px 4px 0 rgba(0,0,0,0.20);border-radius:2px;background:#FFF7D9;font-size:12px;color:#666666;letter-spacing:1px;z-index:8888;transition-property:opacity;transition-duration:.6s;word-wrap: break-word;}';
head.appendChild(style);

// title元素
let wTitleDom = null;
if (!document.getElementById('wTitle')) {
    wTitleDom = document.createElement('div');
    wTitleDom.id = 'wTitle';
    wTitleDom.classList.add('w-title');
    body.appendChild( wTitleDom );
} else {
    wTitleDom = document.getElementById('wTitle');
}

// 函数绑定
function vDirectiveBind(el, eventHandle, callHandle, binding) {
    const Functions = {
        // 鼠标hover进入
        onmouseover() {
            if (el.scrollWidth >= el.offsetWidth) {
                let rect = el.getBoundingClientRect();
                // 取值
                wTitleDom.innerHTML = binding.value;
                // 显示
                wTitleDom.style.display = 'block';
                wTitleDom.style.opacity = 1;
                // 定位
                wTitleDom.style.top = (rect.bottom) + 'px';
                wTitleDom.style.left = (rect.left + 20) + 'px';
                // 控制超出边界
                if (wTitleDom.offsetWidth >= (window.innerWidth - (rect.left + 20))) {
                    wTitleDom.style.maxWidth = (window.innerWidth - (rect.left + 20)) + 'px';
                    // 如果太靠右边则向左扩展
                    if (wTitleDom.offsetWidth <= 170) {
                        wTitleDom.style.maxWidth = (window.innerWidth / 2) + 'px';
                        wTitleDom.style.left = '';
                        wTitleDom.style.right = 0;
                    }
                }
            }
        },
        // 鼠标hover离开
        onmouseleave() {
            wTitleDom.style.opacity = 0
            wTitleDom.style.display = 'none'
        }
    }
    el[eventHandle] = Functions[callHandle];
}

// 定义指令
Vue.directive('w-title', {
    inserted(el, binding, vnode, oldVnode) {
        if (el.scrollWidth > el.offsetWidth) {
            if (wTitleDom) {
                vDirectiveBind(el, 'onmouseover', 'onmouseover', binding);
                vDirectiveBind(el, 'onmouseleave', 'onmouseleave', binding);
                vDirectiveBind(el, 'onclick', 'onmouseleave', binding);
            }
        } else {
            el.onmouseover = null;
            el.onmouseleave = null;
        }
    },
    update(el, binding, vnode, oldVnode) {
        Vue.nextTick(function () {
            if (el.scrollWidth > el.offsetWidth) {
                if (wTitleDom) {
                    vDirectiveBind(el, 'onmouseover', 'onmouseover', binding);
                    vDirectiveBind(el, 'onmouseleave', 'onmouseleave', binding);
                    vDirectiveBind(el, 'onclick', 'onmouseleave', binding);
                }
            } else {
                el.onmouseover = null;
                el.onmouseleave = null;
            }
        });
    },
    componentUpdated(el, binding, vnode, oldVnode) {
    },
    unbind(el, binding, vnode, oldVnode) {
       wTitleDom.style.display = 'none';
       el.onmouseover = null;
       el.onmouseleave = null;
       el.onclick = null;
    }
});
